package com.coocaa.aries.jmeter.thread;

import com.coocaa.aries.core.tool.random.RandomUtil;
import com.coocaa.aries.jmeter.biz.impl.ExtTestCaseBizImpl;
import com.coocaa.aries.jmeter.constant.StreamTypeConstants;
import com.coocaa.aries.jmeter.entity.ExtTestCaseInfoEntity;
import com.coocaa.aries.jmeter.enums.ExecStatusEnums;
import com.coocaa.aries.jmeter.util.CmdUtil;
import com.coocaa.aries.jmeter.util.PathUtil;
import com.coocaa.aries.jmeter.yml.JmeterProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ExecutorService;

/**
 * @author bijiahao
 * @description
 * @date 2020/1/6 11:17
 */
@Slf4j
public class TestCaseExecThread implements Runnable {

    private ExtTestCaseInfoEntity entity;
    private JmeterProperties jmeterProperties;
    private ExtTestCaseBizImpl extTestCaseBiz;

    private Map<Integer, Process> processMap;

    private ExecutorService streamGobblerExecutor;


    public TestCaseExecThread(ExtTestCaseInfoEntity entity, JmeterProperties jmeterProperties, ExtTestCaseBizImpl extTestCaseBiz, Map<Integer, Process> processMap, ExecutorService streamGobblerExecutor) {
        this.entity = entity;
        this.jmeterProperties = jmeterProperties;
        this.extTestCaseBiz = extTestCaseBiz;
        this.processMap = processMap;
        this.streamGobblerExecutor = streamGobblerExecutor;
    }

    @Override
    public void run() {
        String randomDir = RandomUtil.getRandomStoreDir();
        extTestCaseBiz.updateStatusAndReportDir(entity.getId(), randomDir, ExecStatusEnums.EXECUING.getCode());
        String outputDir = PathUtil.getAbsoluteReportStoreDir(randomDir, jmeterProperties);
        String jmxPath = PathUtil.getAbsoluteJmxStorePath(entity, jmeterProperties);
        String cmd = CmdUtil.getJmeterCmd(jmxPath, PathUtil.getAbsoluteJtlStorePath(randomDir, jmeterProperties), outputDir);
        File dir = new File(outputDir);
        try {
            FileUtils.forceMkdir(dir.getParentFile());
        } catch (IOException e) {
            e.printStackTrace();
            extTestCaseBiz.updateStatusAndReportDir(entity.getId(), "", ExecStatusEnums.ERROR.getCode());
            ThreadExecMgr.set(false);
        }
        Runtime runtime = Runtime.getRuntime();
        Process process = null;
        try {
            log.info("exec cmd: " + cmd);
            process = runtime.exec(cmd, null, new File(PathUtil.getJmeterBinDir(jmeterProperties)));
        } catch (IOException e) {
            e.printStackTrace();
            extTestCaseBiz.updateStatusAndReportDir(entity.getId(), "", ExecStatusEnums.ERROR.getCode());
            ThreadExecMgr.set(false);
            return;
        }
        Integer id = entity.getId();
        processMap.put(id, process);
        StreamGobblerThread err = new StreamGobblerThread(id, process.getErrorStream(), StreamTypeConstants.ERROR);
        streamGobblerExecutor.execute(err);
        StreamGobblerThread out = new StreamGobblerThread(id, process.getInputStream(), StreamTypeConstants.STDOUT);
        streamGobblerExecutor.execute(out);
    }
}
